/***********************************************************************
 *
 * MODULE NAME:    sw_resampler.c
 * PROJECT CODE:   BlueStream
 * DESCRIPTION:    Linear PCM up-sampling algorithms.
 * MAINTAINER:     Tom Kerwick
 *
 * SOURCE CONTROL: $Id: sw_resampler.c,v 1.3 2008/08/20 13:14:34 tomk Exp $
 *
 * LICENCE:
 *
 * The routines are Copyright (c) <2008>, <Ceva Inc.> All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * distributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * Neither the name of the Ceva nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 *
 * REVISION HISTORY:
 *
 *  xx.xx.xx Udi Dahan    Original source, stereo upsampler.
 *  15.08.08 Tom Kerwick  Added license terms.
 *  18.08.08 Udi Dahan    Modified for 8K->64K mono upsampling convertor.
 ***********************************************************************/                                 

#include <stdio.h>



short spu_hist[32][2];
short spu_index,spu_step,spu_place_in_buff;
int phase_state =  0;
int phase_step  =  32;  /*convert from 8000 -> 64000*/



/*
Filter type: Low pass
Passband: 0 - 0.0525
Order: 153
Passband ripple: 1.0 dB
Transition band: 0.02
Stopband attenuation: 90.0 dB
*/


const short filter_pass[]={-9, -17, -31, -49, -70, -92, -112, -126, -126, -108, 
-66, 3, 104, 233, 386, 554, 721, 874, 992, 1060, 1061, 987, 835, 611, 331, 20, 
-292, -570, -779, -890, -882, -746, -492, -142, 263, 676, 1039, 1298, 1406, 1333,
1071, 636, 69, -564, -1184, -1704, -2040, -2128, -1927, -1434, -684, 245, 1248,
 2192, 2939, 3362, 3360, 2879, 1923, 558, -1084, -2819, -4422, -5651, -6272, 
 -6090, -4966, -2846, 232, 4137, 8642, 13453, 18224, 22597, 26229, 28829, 30184,
 30184, 28829, 26229, 22597, 18224, 13453, 8642, 4137, 232, -2846, -4966, -6090,
 -6272, -5651, -4422, -2819, -1084, 558, 1923, 2879, 3360, 3362, 2939, 2192, 1248,
 245, -684, -1434, -1927, -2128, -2040, -1704, -1184, -564, 69, 636, 1071, 1333,
 1406, 1298, 1039, 676, 263,-142, -492, -746, -882, -890, -779, -570, -292, 20, 331,
 611, 835, 987, 1061, 1060, 992, 874, 721, 554, 386, 233, 104, 3, -66, -108, -126, 
 -126, -112, -92, -70, -49, -31, -17,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 };




void Init_sample_rate_convert(void)
{
	phase_step = 32; 
	phase_state = 10;
	spu_place_in_buff =0;
}

int CEVA_sample_rate_convert(const short *timeSig,short *outTimeSig,int nof)
{
	int i,j;
	int return_val = 0;
	int filter_ptr;
	int buffer_index;
	long temp_l;


		for(i=0;i<nof;i++)
		{
			spu_place_in_buff--;
			spu_place_in_buff&=31;
			spu_hist[spu_place_in_buff][0] = timeSig[i];

		
			phase_state+=256;  /* 8*32*/ 

			while (phase_state>=phase_step)
			{
				phase_state-=phase_step;
				
					filter_ptr = 7-(phase_state>>5);

					temp_l = 0;
					buffer_index = spu_place_in_buff;
					for(j=0;j<20;j++)
					{
						temp_l+=((long)spu_hist[buffer_index][0]*filter_pass[filter_ptr]);
						filter_ptr+=8 ;
						buffer_index++;
						buffer_index&=31;

					}

					temp_l>>=15;

					if (temp_l>32767)   temp_l=32767;
					if (temp_l<-32767)  temp_l=-32767;
					outTimeSig[return_val]     = (short) (temp_l);
					return_val++;
			}
			
		}
	
	return return_val;
}

#if 0

short s_in[256];
short s_out[1024];

void main()
{
	FILE *fin,*fout;
	short speed_up_ret1;

	fin =  fopen("Face8000_mono.pcm","rb");
	fout = fopen("Face64000_mono.pcm","wb");

    Init_sample_rate_convert();



	while(fread(s_in,sizeof(short)/sizeof(char),50,fin)==50)
	{

		speed_up_ret1=CEVA_sample_rate_convert(s_in,s_out,50);


		fwrite(s_out,sizeof(short)/sizeof(char),speed_up_ret1,fout);
	}

}
#endif
